/**
 * Copyright (c) [2025] [何屹林]
 *
 * 保留所有权利。
 *
 * 文件名称：TreeModel.h
 *
 * 模块功能说明：
 * 该模块树结点的生成，用于可视化AST的树形结构生成。
 *
 * 华南师范大学-计算机学院-网络工程-1班
 * 作者：何屹林-20222132023
 * 完成日期：2025年7月24日
 */
#ifndef TREEMODEL_H
#define TREEMODEL_H

#include <QAbstractItemModel>
#include "utils.h"

class TreeModel : public QAbstractItemModel {
public:

    explicit TreeModel(SyntaxTree root, QObject* parent = nullptr)      //构造，根节点+
        : QAbstractItemModel(parent), rootNode(root) {}

    // 实现必要的虚函数
    QModelIndex index(int row, int column, const QModelIndex& parent) const override {
        if (!hasIndex(row, column, parent)) return {};

        SyntaxNode* parentNode = nodeFromIndex(parent);
        SyntaxNode* childNode = parentNode->children.value(row);
        return createIndex(row, column, childNode);
    }

    QModelIndex parent(const QModelIndex& index) const override {
        if (!index.isValid()) return {};

        SyntaxNode* childNode = static_cast<SyntaxNode*>(index.internalPointer());//当前的结点，或许应该叫currentNode？
        SyntaxNode* parentNode = findParent(rootNode, childNode);

        if (!parentNode || parentNode == rootNode) return {};

        int row = findRow(parentNode);
        return createIndex(row, 0, parentNode);
    }

    int rowCount(const QModelIndex& parent) const override {
        SyntaxNode* parentNode = nodeFromIndex(parent);
        return parentNode ? parentNode->children.size() : 0;
    }

    int columnCount(const QModelIndex&) const override { return 1; }

    QVariant data(const QModelIndex& index, int role) const override {
        if (!index.isValid() || role != Qt::DisplayRole)
            return {};

        SyntaxNode* node = static_cast<SyntaxNode*>(index.internalPointer());
        return node->nodeStr;
    }

    Qt::ItemFlags flags(const QModelIndex&) const override {
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    }

private:
    SyntaxTree rootNode;

    SyntaxNode* nodeFromIndex(const QModelIndex& index) const {
        return index.isValid()
                   ? static_cast<SyntaxNode*>(index.internalPointer())
                   : rootNode;
    }

    SyntaxNode* findParent(SyntaxNode* root, SyntaxNode* target) const {
        if (!root) return nullptr;
        for (SyntaxNode* child : root->children) {
            if (child == target) return root;
            if (SyntaxNode* found = findParent(child, target))
                return found;
        }
        return nullptr;
    }

    int findRow(SyntaxNode* node) const {
        if (SyntaxNode* parent = findParent(rootNode, node)) {
            return parent->children.indexOf(node);
        }
        return 0;
    }
};

#endif // TREEMODEL_H
